package com.loveprogrammer.eternity.model.product;

import com.loveprogrammer.eternity.enums.EquipmentEnum;
import com.loveprogrammer.eternity.enums.MonsterQualityEnum;
import com.loveprogrammer.eternity.enums.QualityEnum;
import com.loveprogrammer.eternity.enums.WeaponTypeEnum;
import com.loveprogrammer.eternity.factory.AffixFactory;
import com.loveprogrammer.eternity.factory.EquipmentFactory;
import com.loveprogrammer.eternity.factory.GoodsFactory;
import com.loveprogrammer.eternity.factory.template.MapTemplate;
import com.loveprogrammer.eternity.model.Hero;
import com.loveprogrammer.eternity.model.Monster;
import com.loveprogrammer.eternity.model.console.ConsolePrint;
import com.loveprogrammer.eternity.model.product.eggs.Egg;
import com.loveprogrammer.eternity.model.product.equipment.Weapon;
import com.loveprogrammer.eternity.utils.RandomBalance;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @version 1.0.0
 * @description: 掉落物品计算器
 * @author: eric
 * @date: 2022-08-04 16:54
 **/
public class FallingGoodsCalculator implements FallingGoods {

    private Monster monster;

    public FallingGoodsCalculator() {
    }

    public FallingGoodsCalculator(Monster monster) {
        this.monster = monster;
    }

    @Override
    public FallingGoods setMonster(Monster monster) {
        this.monster = monster;
        return this;
    }

    @Override
    public Equipment getCasinoEquipmentByHero(Hero hero, int level, EquipmentEnum equipmentEnum) {
        switch (level) {
            case 1:
                return calculator(hero, 800, 200, 10, 0, 0, 0, 0, equipmentEnum);
            case 2:
                return calculator(hero, 0, 800, 100, 5, 0, 0, 0, equipmentEnum);
            case 3:
                return calculator(hero, 0, 0, 800, 200, 20, 0, 0, equipmentEnum);
            case 4:
                return calculator(hero, 0, 0, 0, 1000, 100, 20, 0, equipmentEnum);
            case 5:
                return calculator(hero, 0, 0, 0, 600, 300, 100, 0, equipmentEnum);
            case 6:
                return calculator(hero, 0, 0, 0, 0, 700, 300, 0, equipmentEnum);
            case 7:
                return calculator(hero, 0, 0, 0, 0, 500, 500, 0, equipmentEnum);
            default:
                break;

        }

        return null;
    }

    @Override
    public List<Goods> getFallingProduct() {
        // 根据自身的级别掉落
        //   普通  整体15%   白色 1000 蓝色 50 黄色 10
        //   变异  整体25%   白色 1000 蓝色 200 黄色 20 紫色 5
        //   史诗  整体35%   蓝色 1000 黄色 200 紫色 50 红色 20
        //   传奇  整体55%   黄色 1000 紫色 200 红色 50 暗金 20
        //   神话  整体100%  紫色 1000 红色 200 暗金 50 绿色 20
        if (monster.getMonsterQualityEnum() != null) {
            switch (monster.getMonsterQualityEnum().getCode()) {
                case 1:
                    return calculator(monster, 1000, 50, 10, 0, 0, 0, 0);
                case 2:
                    return calculator(monster, 1000, 200, 20, 5, 0, 0, 0);
                case 3:
                    return calculator(monster, 0, 1000, 200, 50, 20, 0, 0);
                case 4:
                    return calculator(monster, 0, 0, 1000, 200, 40, 20, 0);
                case 5:
                    return calculator(monster, 0, 0, 0, 1000, 200, 30, 30);
                default:
                    break;
            }
        }

        Weapon equipment = new Weapon("木剑", "武器", "最基本的武器", EquipmentEnum.WEAPON,
                WeaponTypeEnum.SWORD,
                QualityEnum.白色,0);
        equipment.setStrength(5);
        equipment.setSpeed(5);
        List<Goods> goods = new ArrayList<>();
        goods.add(equipment);
        return goods;
    }

    @Override
    public List<Goods> getFallingProduct(List<MapTemplate.Drop> dropList) {
        List<Goods> fallingProduct = getFallingProduct();

        if(dropList != null) {
            // 看是否能命中dropList 基础值是20万
            for (MapTemplate.Drop drop : dropList) {
                int percents = drop.getPercents();
                if (new Random().nextInt(200000) < percents) {
                    int goodsId = drop.getGoodsId();
                    String type = drop.getGoodsType();
                    Goods goods = GoodsFactory.getGoodsById(type, goodsId, null);
                    if (goods != null)
                        fallingProduct.add(goods);
                }
            }
        }
        return fallingProduct;

    }

    private List<Goods> calculator(Monster monster, int white, int blue, int yellow,
                                   int purple, int red, int gold, int green) {
        List<Goods> result = new ArrayList<>();

        // 首先确定是否掉落
        MonsterQualityEnum qualityEnum = monster.getMonsterQualityEnum();
        int percent = qualityEnum.getPercent();
        int nextInt = new Random().nextInt(1000);
        if (nextInt > percent) {
            return new ArrayList<>();
        }

        // 第二确定掉落的种类 当前就是装备 掉落伴生卵的概率默认10%
        if (nextInt < qualityEnum.getPercentEgg()) {
            ConsolePrint.publishMessage("掉落了伴生卵");
            Egg egg = new Egg(monster.getName() + "的卵", "egg", ""
                    , QualityEnum.getById(new Random().nextInt(6)), monster.getTemplate());
            result.add(egg);
        } else {
            // 第三 不是卵就是装备，确定装备的品类
            QualityEnum equipQuality = RandomBalance.findQuality(white, blue, yellow, purple, red, gold, green);
            // 如果是装备，要看是哪个装备
            Equipment equipment = EquipmentFactory.createEquipment(monster, equipQuality);
            result.add(equipment);
        }
        return result;
    }


    private Equipment calculator(Hero hero, int white, int blue, int yellow,
                                 int purple, int red, int gold, int green, EquipmentEnum equipmentEnum) {

        // 确定装备的品类
        QualityEnum equipQuality = RandomBalance.findQuality(white, blue, yellow, purple, red, gold, green);
        // 如果是装备，要看是哪个装备
        Equipment equipment = EquipmentFactory.createEquipment(hero, equipQuality, equipmentEnum);
        if(equipment != null){
            return AffixFactory.setAffix(equipment);
        }
        return null;
    }
}
